import { extname, join, parse } from "path";
import { Handler } from "./Handler";
import { Environment } from "./Environment";
import { AssetInfo, FileResult, LibraryMaps } from "./Defines";
import { existsSync, readFileSync, writeFileSync } from "fs";
import { FileUtils } from "./FileUtils";

export default class AssetsHelper extends Handler {
    static readonly module = "【AssetsHelper】";

    protected get libraryPath(): string {
        return join(this.projPath, "snack/library");
    }

    protected get internalInfoPath(): string {
        if (Environment.isVersion3X) {
            return join(this.projPath, "snack/library/.internal-info.json");
        }
        return join(Environment.creatorPath, "static/default-assets/image");
    }

    protected _internalInfo: Map<string, AssetInfo> = null!;
    /**@description 获取内部资源信息 */
    protected get internalInfo(): Map<string, AssetInfo> {
        if (this._internalInfo) {
            return this._internalInfo;
        }
        if (Environment.isVersion3X) {
            let dataStr = readFileSync(this.internalInfoPath, "utf-8");
            let data = JSON.parse(dataStr);
            let keys = Object.keys(data);
            this._internalInfo = new Map<string, AssetInfo>();
            keys.forEach(key => {
                let info: AssetInfo = {
                    uuid: data[key].uuid,
                    type: "internal",
                    file: key,
                }
                this._internalInfo.set(info.uuid, info);
            });
        } else {
            let info: AssetInfo = {
                uuid: "",
                type: "internal",
                file: ""
            };
            this._internalInfo = new Map<string, AssetInfo>();
            FileUtils.getFiles(this.internalInfoPath, (file) => {
                if (extname(file.name) == ".meta") {
                    let dataStr = readFileSync(file.path, "utf-8");
                    let data = JSON.parse(dataStr);
                    info.uuid = data.uuid;
                    let temp = parse(file.path);
                    info.path = join(temp.dir, `${temp.name}`);
                    this._internalInfo.set(info.uuid, info);
                }
                return false;
            });
        }
        return this._internalInfo;
    }

    protected queryAssets: Map<string, AssetInfo> = null!;

    protected isPngAsset(type: string): boolean {
        if (Environment.isVersion3X) {
            if (type == "cc.ImageAsset" || type == "cc.SpriteAtlas") {
                return true;
            }
        } else {
            if (type == "cc.Texture2D") {
                return true;
            }
        }
        return false;
    }

    /**
     * @description 处理library目录下的json资源
     * @param info 
     */
    private handleLibraryJson(info: FileResult) {
        let ext = extname(info.name);
        if (ext == ".json") {
            let dataStr = readFileSync(info.path, "utf-8");
            let data = JSON.parse(dataStr);
            let type = data.__type__;
            let result = this.isPngAsset(type);
            if (result) {
                let lib: LibraryMaps = {
                    ".json": info.path,
                    ".png": "",
                };

                if (!Environment.isVersion3X) {
                    let temp = parse(info.path);
                    let pngPath = join(temp.dir, `${temp.name}.png`);
                    if (existsSync(pngPath)) {
                        lib[".png"] = pngPath;
                    }
                }

                let uuid = this.getUUID(info.name);

                let _info: AssetInfo = {
                    uuid: uuid,
                    type: type,
                    library: lib,
                }
                this.queryAssets.set(uuid, _info);
            }
        }
    }

    /**
     * @description 处理library目录下的png资源
     * @param info 
     */
    private handleLibraryPng(info: FileResult) {
        let ext = extname(info.name);
        if (ext == ".png") {
            let uuid = this.getUUID(info.name);
            if (!this.internalInfo.has(uuid)) {
                let obj = this.queryAssets.get(uuid);
                if (obj && obj.library) {
                    obj.library[".png"] = info.path;
                }
            }
        }
    }

    /**
     * @description 处理assets目录下的meta资源
     * @param info 
     */
    private handleAssetsMeta(info: FileResult) {
        let ext = extname(info.name);
        if (ext == ".meta") {
            let result = parse(info.name);
            result = parse(result.name);
            if (result.ext == ".png") {
                let dataStr = readFileSync(info.path, "utf-8");
                let data = JSON.parse(dataStr);
                let uuid = data.uuid;
                if (!this.internalInfo.has(uuid)) {
                    let obj = this.queryAssets.get(uuid);
                    if (obj) {
                        obj.path = join(parse(info.path).dir, result.name);
                    } else {
                        this.logger.warn(`${AssetsHelper.module} 未找到资源 : ${info.name}`);
                    }
                }
            } else if (result.ext == ".pac") {
                let dataStr = readFileSync(info.path, "utf-8");
                let data = JSON.parse(dataStr);
                let uuid = data.uuid;
                if (!this.internalInfo.has(uuid)) {
                    let obj = this.queryAssets.get(uuid);
                    if (obj) {
                        obj.path = join(parse(info.path).dir, result.name);
                    } else {
                        this.logger.warn(`${AssetsHelper.module} 未找到资源 : ${info.name}`);
                    }
                }
            }
        }
    }

    public async getAssets() {
        this.queryAssets = new Map<string, AssetInfo>();
        this.logger.log(`${this.module} 查询资源开始...${this.libraryPath}`);
        // FileUtils.getFiles(this.libraryPath, (info) => {
        //     this.handleLibraryJson(info);
        //     if (Environment.isVersion3X) {
        //         this.handleLibraryPng(info);
        //     }
        //     return false;
        // });
        // FileUtils.getFiles(this.assetsDBPath, (info) => {
        //     this.handleAssetsMeta(info);
        //     return false;
        // });
        // // writeFileSync(join(__dirname, "../../test.json"), JSON.stringify(this.queryAssets));
        // let values = Object.values(this.queryAssets);
        // // writeFileSync(join(__dirname, "../../test2.json"), JSON.stringify(values));
        // return values;
    }
}